﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Chilkat;
using System.Windows.Forms;
using System.Text.RegularExpressions;

namespace WebServiceClient
{
    public class Helpers : IUserAuth
    {
        private static readonly string domain = "localhost";
        private static readonly int port = 88;
        private static readonly string memory = @"C:\Cookies\";
        private static readonly string location = "";

        private static List<Algorithm> algorithms = new List<Algorithm>();

        public bool Authorize(string login, string password)
        {
            HttpRequest req = new HttpRequest();
            Http http = new Http();

            bool success;

            success = http.UnlockComponent("");
            if (success != true)
            {
                MessageBox.Show(http.LastErrorText);
                return false;
            }

            http.CookieDir = Helpers.memory;
            http.SendCookies = true;
            http.SaveCookies = true;

            string html;
            html = http.QuickGetStr("http://" + Helpers.domain + ":" + Helpers.port + "/");
            if (html == null)
            {
                return false;
            }
            req.UsePost();
            req.Path = "/";
            req.AddParam("l", login);
            req.AddParam("p", password);

            req.AddHeader("Referer", "http://" + Helpers.domain + ":" + Helpers.port + "/");

            bool ssl;
            ssl = false;
            HttpResponse resp;
            resp = http.SynchronousRequest(domain, port, ssl, req);
            if (resp == null)
            {
                return false;
            }

            if (resp.StatusCode == 302)
            {
                string redirectUrl;
                redirectUrl = resp.GetHeaderField(Helpers.location);

                html = http.QuickGetStr(redirectUrl);
            }

            if (resp.NumCookies > 0)
                return true;
            else
                return false;

        }

        public List<Algorithm> GetAlgorithms(string login, string password)
        {
            HttpRequest req = new HttpRequest();
            Http http = new Http();

            bool success;
            success = http.UnlockComponent("");

            http.CookieDir = "memory";
            http.SendCookies = true;
            http.SaveCookies = true;

            string html;
            html = http.QuickGetStr("http://" + Helpers.domain + ":" + Helpers.port + "/");

            req.UsePost();
            req.Path = "/";
            req.AddParam("l", login);
            req.AddParam("p", password);


            req.AddHeader("Referer", "http://" + Helpers.domain + ":" + Helpers.port + "/");

            bool ssl;
            ssl = false;
            HttpResponse resp;
            resp = http.SynchronousRequest(Helpers.domain, Helpers.port, ssl, req);

            req.Path = "/list.htm";
            req.RemoveAllParams();
            resp = http.SynchronousRequest(Helpers.domain, Helpers.port, ssl, req);

            var names = getNames(resp.BodyStr);
            var ids = getIds(resp.BodyStr);
            List<bool> rights = new List<bool>();
            foreach (var item in ids)
            {
                rights.Add(canEdit(item, resp.BodyStr));
            }

            List<Algorithm> result = new List<Algorithm>();

            for (int i = 0; i < names.Count; i++)
            {
                result.Add(new Algorithm { Id = ids[i], Name = names[i], CanEdit = rights[i] } );
            }

            Form1.algorithms = result;

            return result;
        }

        public string GetAlgorithmByName(string login, string password, string name)
        {
            HttpRequest req = new HttpRequest();
            Http http = new Http();

            bool success;
            success = http.UnlockComponent("");

            http.CookieDir = "memory";
            http.SendCookies = true;
            http.SaveCookies = true;

            string html;
            html = http.QuickGetStr("http://" + Helpers.domain + ":" + Helpers.port + "/");

            req.UsePost();
            req.Path = "/";
            req.AddParam("l", login);
            req.AddParam("p", password);

            req.AddHeader("Referer", "http://" + Helpers.domain + ":" + Helpers.port + "/");

            bool ssl;
            ssl = false;
            HttpResponse resp;
            resp = http.SynchronousRequest(Helpers.domain, Helpers.port, ssl, req);

            string index = string.Empty;

            foreach (var item in Form1.algorithms)
	        {
                if (item.Name == name)
                    index = item.Id;
	        }

            req.UseGet();

            req.Path = "/edit.htm?algid=" + index;
            req.RemoveAllParams();
            resp = http.SynchronousRequest(Helpers.domain, Helpers.port, ssl, req);

            string code = getCode(resp.BodyStr);

            return code;
        }

        public string GetAlgorithmDescriptionByName(string login, string password, string name)
        {
            HttpRequest req = new HttpRequest();
            Http http = new Http();

            bool success;
            success = http.UnlockComponent("");

            http.CookieDir = "memory";
            http.SendCookies = true;
            http.SaveCookies = true;

            string html;
            html = http.QuickGetStr("http://" + Helpers.domain + ":" + Helpers.port + "/");

            req.UsePost();
            req.Path = "/";
            req.AddParam("l", login);
            req.AddParam("p", password);

            req.AddHeader("Referer", "http://" + Helpers.domain + ":" + Helpers.port + "/");

            bool ssl;
            ssl = false;
            HttpResponse resp;
            resp = http.SynchronousRequest(Helpers.domain, Helpers.port, ssl, req);

            string index = string.Empty;

            foreach (var item in Form1.algorithms)
            {
                if (item.Name == name)
                    index = item.Id;
            }

            req.UseGet();

            req.Path = "/edit.htm?algid=" + index;
            req.RemoveAllParams();
            resp = http.SynchronousRequest(Helpers.domain, Helpers.port, ssl, req);

            string desc = getDescription(resp.BodyStr);

            return desc;
        }

        public void SaveAlgorithm(string login, string password, string oldName ,string name, string desc, string code)
        {
            HttpRequest req = new HttpRequest();
            Http http = new Http();

            bool success;
            success = http.UnlockComponent("");

            http.CookieDir = "memory";
            http.SendCookies = true;
            http.SaveCookies = true;

            string html;
            html = http.QuickGetStr("http://" + Helpers.domain + ":" + Helpers.port + "/");

            req.UsePost();
            req.Path = "/";
            req.AddParam("l", login);
            req.AddParam("p", password);

            req.AddHeader("Referer", "http://" + Helpers.domain + ":" + Helpers.port + "/");

            bool ssl;
            ssl = false;
            HttpResponse resp;
            resp = http.SynchronousRequest(Helpers.domain, Helpers.port, ssl, req);

            string index = string.Empty;

            foreach (var item in Form1.algorithms)
            {
                if (item.Name == oldName)
                    index = item.Id;
            }

            req.Path = "/edit.htm?algid=" + index;
            req.RemoveAllParams();
            req.AddParam("name", name);
            req.AddParam("desc", desc);
            req.AddParam("code", code);
            resp = http.SynchronousRequest(Helpers.domain, Helpers.port, ssl, req);
        }

        public List<string> GetGroups(string login, string password)
        {
            HttpRequest req = new HttpRequest();
            Http http = new Http();

            bool success;
            success = http.UnlockComponent("");

            http.CookieDir = "memory";
            http.SendCookies = true;
            http.SaveCookies = true;

            string html;
            html = http.QuickGetStr("http://" + Helpers.domain + ":" + Helpers.port + "/");

            req.UsePost();
            req.Path = "/";
            req.AddParam("l", login);
            req.AddParam("p", password);

            req.AddHeader("Referer", "http://" + Helpers.domain + ":" + Helpers.port + "/");

            bool ssl;
            ssl = false;
            HttpResponse resp;
            resp = http.SynchronousRequest(Helpers.domain, Helpers.port, ssl, req);

            req.Path = "/upload.htm";
            req.RemoveAllParams();
            resp = http.SynchronousRequest(Helpers.domain, Helpers.port, ssl, req);

            var res = findGroups(resp.BodyStr);
            return res;
        }

        public void RemoveAlgorithm(string login, string password, string name)
        {
            HttpRequest req = new HttpRequest();
            Http http = new Http();

            bool success;
            success = http.UnlockComponent("");

            http.CookieDir = "memory";
            http.SendCookies = true;
            http.SaveCookies = true;

            string html;
            html = http.QuickGetStr("http://" + Helpers.domain + ":" + Helpers.port + "/");

            req.UsePost();
            req.Path = "/";
            req.AddParam("l", login);
            req.AddParam("p", password);

            req.AddHeader("Referer", "http://" + Helpers.domain + ":" + Helpers.port + "/");

            bool ssl;
            ssl = false;
            HttpResponse resp;
            resp = http.SynchronousRequest(Helpers.domain, Helpers.port, ssl, req);

            string index = string.Empty;

            foreach (var item in Form1.algorithms)
            {
                if (item.Name == name)
                    index = item.Id;
            }

            req.Path = "/del.htm?algid=" + index;
            req.RemoveAllParams();
            resp = http.SynchronousRequest(Helpers.domain, Helpers.port, ssl, req);
        }

        private List<string> getNames(string str)
        {
            string regExpAlgName = @"(?<=\<tr\>\<td\>).*?(?=\<\/td\>)";
            Regex regex = new Regex(regExpAlgName);
            Match match = regex.Match(str);
            List<string> tmp = new List<string>();
            while (match.Success)
            {
                tmp.Add(match.Value);
                match = match.NextMatch();
            }
            return tmp;
        }

        private List<string> getIds(string str)
        {
            string regExpAlgName = @"(?<=\/run\.htm\?algid\=).*?(?="")";
            Regex regex = new Regex(regExpAlgName);
            Match match = regex.Match(str);
            List<string> tmp = new List<string>();
            while (match.Success)
            {
                tmp.Add(match.Value);
                match = match.NextMatch();
            }
            return tmp;
        }

        private string getCode(string str)
        {
            string regExpAlgName = @"(?<= \<textarea name\=""code"" rows\=""\d+"" \>)[\w\W]*?(?=\<\/textarea\>)";
            Regex regex = new Regex(regExpAlgName);
            Match match = regex.Match(str);
            List<string> tmp = new List<string>();
            while (match.Success)
            {
                tmp.Add(match.Value);
                match = match.NextMatch();
            }
            return tmp.FirstOrDefault();
        }

        private string getDescription(string str)
        {
            string regExpAlgName = @"(?<=\<textarea name\=""desc"" rows\=""\d+"" \>)[\w\W]*?(?=\<\/textarea\>)";
            Regex regex = new Regex(regExpAlgName);
            Match match = regex.Match(str);
            List<string> tmp = new List<string>();
            while (match.Success)
            {
                tmp.Add(match.Value);
                match = match.NextMatch();
            }
            return tmp.FirstOrDefault();
        }

        private List<string> findGroups(string str)
        {
            string regExpAlgName = @"(?<=\<tr\>\<td\>).*?(?=\<\/td\>\<td\>\<input name\=""chb_read)";
            Regex regex = new Regex(regExpAlgName);
            Match match = regex.Match(str);
            List<string> tmp = new List<string>();
            while (match.Success)
            {
                tmp.Add(match.Value);
                match = match.NextMatch();
            }
            return tmp;
        }

        private bool canEdit(string id, string str)
        {
           string regExpCanRun = @"/edit.htm\?algid=" + id + @""">";
           Regex regex = new Regex(regExpCanRun);
           Match match = regex.Match(str);
           if(match.Success) return true;
           else return false;
        }

        
    }
}
